package com.alquiler.implementation;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import com.alquiler.dto.ItemDto;
import com.alquiler.entities.AbstractEntity;
import com.alquiler.utils.idItem;
import com.alquiler.utils.valueItem;



public abstract class GenericDaoImpl<E extends AbstractEntity, K, I>  implements IGenericDao<E, K, I>{	
	
	
	protected Class<E> entityClass;

    @PersistenceContext
    protected EntityManager entityManager;	
    
    @SuppressWarnings("unchecked")
	public GenericDaoImpl(EntityManager entityManager) {
        this.entityManager = entityManager;
        this.entityClass = (Class<E>) this.getTypeClass();
    }
    
	@Override
    public E save(final E entity) {
		entityManager.persist(entity);
        return entity;
    }
 
    @Override
    public E update(final E entity) {
        return entityManager.merge(entity);
    }
 
    @Override
    public void remove(final E entity) {
    	entityManager.remove(entityManager.merge(entity));
    }
 
    @Override
    public E findById(final K id) {
        return entityManager.find(entityClass, id);
    } 
  
   
	@SuppressWarnings("unchecked")
	@Override	
	public List<E> findAll() {
        return entityManager.createQuery(("FROM " + entityClass.getName()))
                .getResultList();
    }
	
	@SuppressWarnings("unchecked")
	public List<E> findCanchasDisponibles() {
        return entityManager.createQuery(("FROM " + entityClass.getName() + " ent WHERE ent.estado = 0"))
                .getResultList();
    }
	
	
	@SuppressWarnings("unchecked")
	public List<I> getListItems() {
		
		String idPropertie =null ;			
		String namePropertie = null;
		
        Field[] fields = entityClass.getDeclaredFields();
 
        for (Field field : fields){
        	
        	if(field.isAnnotationPresent(idItem.class)){
        		idPropertie = field.getName();
        		
        	}else if(field.isAnnotationPresent(valueItem.class)){
        		namePropertie = field.getName();	        		
        	}
           
        }
        
        if(idPropertie != null && namePropertie != null){
        	 return entityManager.createQuery(("Select new "+ ItemDto.class.getCanonicalName() +" ("+idPropertie+","+namePropertie+") FROM " + entityClass.getName()))
                     .getResultList();        	
        }else{
        	return new ArrayList<I>();
        }	
       
    }
	
	
 
    @Override
    public Long getTotalResult() {
        return (Long) entityManager.createQuery("select count(e) from "+entityClass.getName()+" e").getSingleResult();
    }
    
   
    private Class<?> getTypeClass() {
        Class<?> clazz = (Class<?>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        return clazz;
    }

}
